package com.geovis.emergency.spd.biz.pc.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.geovis.common.core.constant.CommonConstants;
import com.geovis.emergency.spd.biz.basic.service.IBasicDutyOrgService;
import com.geovis.emergency.spd.biz.command.service.TfService;
import com.geovis.emergency.spd.biz.pc.mapper.*;
import com.geovis.emergency.spd.biz.pc.service.*;
import com.geovis.emergency.spd.biz.system.service.*;
import com.geovis.emergency.spd.biz.system.wrapper.ForestNodeMerger;
import com.geovis.emergency.spd.cache.DictCache;
import com.geovis.emergency.spd.entity.basic.pojo.dto.BasicDutyOrgTreeDTO;
import com.geovis.emergency.spd.entity.command.enums.PlanFileTypeEnum;
import com.geovis.emergency.spd.entity.command.pojo.vo.*;
import com.geovis.emergency.spd.entity.pc.entity.*;
import com.geovis.emergency.spd.entity.pc.pojo.constant.PcDisasterConstant;
import com.geovis.emergency.spd.entity.pc.pojo.constant.PcDrillConstant;
import com.geovis.emergency.spd.entity.pc.pojo.dto.PcDrillDisasterEventQueryDTO;
import com.geovis.emergency.spd.entity.pc.pojo.dto.PcDrillDisasterSchedulingDTO;
import com.geovis.emergency.spd.entity.pc.pojo.dto.PcDrillDisasterSubmitDTO;
import com.geovis.emergency.spd.entity.pc.pojo.enums.*;
import com.geovis.emergency.spd.entity.pc.pojo.vo.*;
import com.geovis.emergency.spd.entity.system.constant.SystemFileBusinessConstant;
import com.geovis.emergency.spd.entity.system.entity.*;
import com.geovis.emergency.spd.entity.system.pojo.dto.SystemFileDTO;
import com.geovis.emergency.spd.entity.system.pojo.dto.SystemFileQueryDTO;
import com.geovis.emergency.spd.entity.system.pojo.vo.SystemDeptTreeVO;
import com.geovis.emergency.spd.entity.system.pojo.vo.SystemUserVo;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * <p>
 * 应急预案指挥模块-演练灾害表 服务实现类
 * </p>
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class PcDrillDisasterServiceImpl extends ServiceImpl<PcDrillDisasterMapper, PcDrillDisaster> implements IPcDrillDisasterService {
    private final PcDisasterMapper pcDisasterMapper;
    private final PcDrillDisasterMapper pcDrillDisasterMapper;

    private final PcDrillMapper pcDrillMapper;

    private final PcDrillDisasterEventMapper pcDrillDisasterEventMapper;
    private final PcDisasterEventMapper pcDisasterEventMapper;

    private final IPcDrillDisasterEventService pcDisasterEventService;

    private final ISystemFileBusinessService systemFileBusinessService;
    private final ISystemFileService systemFileService;

    private final IPcDrillDutyOrgService pcDutyOrgService;

    private final IPcPlanDutyOrgService pcPlanDutyOrgService;
    private final IPcPlanDutyOrgDeptService pcPlanDutyOrgDeptService;

    private final IPcDrillDutyUserService pcDrillUserService;
    private final IPcDrillDutyOrgService pcDrillDutyOrgService;

    private final IPcDrillPlanService pcDrillPlanList;




    private final IPcPlanDutyDeptService pcPlanDutyDeptService;

    private final ISystemDeptUserService systemDeptUserService;

    private final ISystemUserService systemUserService;

    private final IPcSchedulingEventService schedulingEventService;

    private final IBasicDutyOrgService basicDutyOrgService;

    private final IPcSchedulingEventStatisticsService pcSchedulingEventStatisticsService;

    private final PcDrillPlanDetailMapper pcDrillPlanDetailMapper;

    private final PcDrillDutyOrgMapper pcDrillDutyOrgMapper;

    private final ISystemDeptService systemDeptService;

    private final TfService tfService;

    private final PcDrillDutyUserMapper pcDrillDutyUserMapper;

    private final IPcDrillUserRoleService pcDrillUserRoleService;

    private final PcPlanOrgUserMapper pcPlanOrgUserMapper;

    private final IPcDisasterEventService disasterEventService;




    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitEvent(PcDrillDisasterSubmitDTO saveDTO) {
        PcDrill pcDrill = pcDrillMapper.selectById(saveDTO.getPcDrillId());
        Assert.notNull(pcDrill, "演练不存在");
        Assert.isFalse(PcDrillConstant.STATUS_COMPLETE.equals(pcDrill.getStatus()),"该演练已经结束了");
        Assert.isFalse(PcDrillConstant.STATUS_DOING.equals(pcDrill.getStatus()),"该演练正在进行中");
        //灾害事件列表
        Map<String, List<PcDrillDisasterEvent>> disasterIdMap = IterUtil.toListMap(saveDTO.getDisasterEventList(), PcDrillDisasterEvent::getId);
        Map<String, List<PcDrillDisasterEvent>> disasterMap = saveDTO.getDisasterEventList().stream().collect(Collectors.groupingBy(PcDrillDisasterEvent::getPcDisasterId,LinkedHashMap::new,Collectors.toList()));

        //查询不在提交列表中的灾害事件，已经删除了
        List<PcDrillDisasterEvent> pcDrillDisasterEvents = pcDrillDisasterEventMapper.selectList(Wrappers.<PcDrillDisasterEvent>lambdaQuery()
                .eq(PcDrillDisasterEvent::getPcDrillId, saveDTO.getPcDrillId())
                .notIn(PcDrillDisasterEvent::getId, disasterIdMap.keySet())
                .select(PcDrillDisasterEvent::getId,PcDrillDisasterEvent::getPcDrillDisasterId));
        for (PcDrillDisasterEvent pcDrillDisasterEvent : pcDrillDisasterEvents) {
            //移除事件
            removeEvent(saveDTO.getPcDrillId(), pcDrillDisasterEvent.getId(),pcDrillDisasterEvent.getPcDrillDisasterId());
        }
        LocalDateTime now=LocalDateTime.now();
        AtomicInteger index = new AtomicInteger(0);
        //演练类型
        String drillType=pcDrill.getDrillType();
        //先清空事件消息
        pcDrillDisasterEventMapper.delete(
                Wrappers.<PcDrillDisasterEvent>lambdaQuery()
                        .eq(PcDrillDisasterEvent::getPcDrillId, pcDrill.getId())
        );

        for (Map.Entry<String, List<PcDrillDisasterEvent>> entry : disasterMap.entrySet()) {
            //设置PcDrillDisaster
            PcDrillDisaster pcDrillDisaster = baseMapper.selectOne(
                    Wrappers.<PcDrillDisaster>lambdaQuery()
                            .eq(PcDrillDisaster::getPcDrillId,saveDTO.getPcDrillId())
                            .eq(PcDrillDisaster::getPcDisasterId,entry.getKey())
            );
            if (ObjectUtil.isNull(pcDrillDisaster)){
                pcDrillDisaster = new PcDrillDisaster()
                        .setPcDrillId(saveDTO.getPcDrillId())
                        .setPcDisasterId(entry.getKey());
                PcDisaster pcDisaster = pcDisasterMapper.selectById(entry.getKey());
                BeanUtil.copyProperties(pcDisaster, pcDrillDisaster);
                pcDrillDisaster.setIdx(index.incrementAndGet());
                pcDrillDisaster.setId(null);
                pcDrillDisaster.setSourceType(SourceTypeEnum.REPOSITORY.getCode());
                //和演练关联之后，如果是指挥演练，是实际的场景，提交时间应该为当前时间
//                if(DrillTypeEnum.EMERGENCY_COMMAND.equals(drillType))
//                {
//                    pcDrillDisaster.setCreateTime(now);
//                }
                //演练关联灾害id
                baseMapper.insert(pcDrillDisaster);
            }else {
                pcDrillDisaster.setIdx(index.incrementAndGet());
                pcDrillDisaster.setUpdateTime(now);
                baseMapper.updateById(pcDrillDisaster);
            }
            if (EventTypeEnum.MAIN_EVENT.getCode().equals(pcDrillDisaster.getEventType())){
                //演练关联预案
                pcDrill.setPcPlanId(pcDrillDisaster.getPcPlanId());
            }
            //保存演练事件消息
            saveDrillDisasterEvent(entry.getValue(),pcDrill,pcDrillDisaster.getId());
        }


        //保存组织架构与人员
        if (CollUtil.isNotEmpty(saveDTO.getDutyOrgList())){
            pcDrillDutyOrgService.removeDutyOrg(saveDTO.getDutyOrgList(),pcDrill.getId());
            //先删除存在的演练与用户角色关联记录，不可以在下面saveDrillDutyOrg里面删除，下面是一个递归调用的方案
            pcDrillUserRoleService.remove(Wrappers.lambdaQuery(PcDrillUserRole.class)
                    .eq(PcDrillUserRole::getPcDrillId,saveDTO.getPcDrillId()));
            pcDrillDutyOrgService.saveDrillDutyOrg(saveDTO.getDutyOrgList(),pcDrill.getId(),null,null);
        }
        pcDrillMapper.updateById(pcDrill);
    }


    private void saveDrillDisasterEvent(List<PcDrillDisasterEvent> events, PcDrill pcDrill, String pcDrillDisasterId)
    {

        LocalDateTime now=LocalDateTime.now();
        for (PcDrillDisasterEvent pcDrillDisasterEventDTO : events) {
            PcDrillDisasterEvent pcDrillDisasterEvent = new PcDrillDisasterEvent();
            BeanUtil.copyProperties(pcDrillDisasterEventDTO, pcDrillDisasterEvent);
            pcDrillDisasterEvent.setPcDrillId(pcDrill.getId());
            pcDrillDisasterEvent.setPcDrillDisasterId(pcDrillDisasterId);
            pcDrillDisasterEvent.setSourceType(SourceTypeEnum.REPOSITORY.getCode());
            pcDrillDisasterEvent.setStatus(DisasterEventStatusEnum.TO_BE_ISSUED.getCode());
            //和演练关联之后，如果是指挥演练，是实际的场景，提交时间应该为当前时间
//            if(DrillTypeEnum.EMERGENCY_COMMAND.getCode().equals(pcDrill.getDrillType()))
//            {
//                if(!EventTypeEnum.MAIN_EVENT.getCode().equals(pcDrillDisaster.getEventType()))
//                {
//                    pcDrillDisasterEvent.setSubmitTime(now);
//                }
//            }
            pcDrillDisasterEvent.setId(null);
            //演练关联灾害id
            pcDrillDisasterEventMapper.insert(pcDrillDisasterEvent);
            //管理附件
            saveFiles(pcDrillDisasterEvent.getPcDisasterEventId(),pcDrillDisasterEvent.getId());
        }
    }

    private void saveFiles(String pcDisasterEventId,String pcDrillDisasterEventId)
    {


        SystemFileQueryDTO systemFileQueryDTO = new SystemFileQueryDTO();
        systemFileQueryDTO.setRelatedId(pcDisasterEventId);
        systemFileQueryDTO.setType(SystemFileBusinessConstant.TYPE_PC_DISASTER_EVENT);
        List<SystemFileDTO> list = systemFileService.getList(systemFileQueryDTO);
        Set<SystemFileBusiness> fileBusinessSet = CollUtil.set(false);
        for (SystemFileDTO systemFile : list) {
            fileBusinessSet.add(new SystemFileBusiness(systemFile.getId(), SystemFileBusinessConstant.TYPE_PC_DRILL_DISASTER_EVENT, pcDrillDisasterEventId));
        }
        systemFileBusinessService.saveBatch(fileBusinessSet);

    }
    @Override
    public void schedulingSubmitEvent(PcDrillDisasterSchedulingDTO saveDTO){
        PcDrill pcDrill = pcDrillMapper.selectById(saveDTO.getPcDrillId());
        Assert.notNull(pcDrill, "演练不存在");
        Assert.isFalse(PcDrillConstant.STATUS_COMPLETE.equals(pcDrill.getStatus()),"该演练已经结束了");
        Assert.isFalse(PcDrillConstant.STATUS_DOING.equals(pcDrill.getStatus()),"该演练正在进行中");

        //保存组织架构
        if (CollUtil.isNotEmpty(saveDTO.getDutyOrgList())){
            pcDrillDutyOrgService.removeDutyOrg(saveDTO.getDutyOrgList(),pcDrill.getId());
            pcDrillDutyOrgService.saveDrillDutyOrg(saveDTO.getDutyOrgList(),pcDrill.getId(),null,null);
        }
        //保存事件消息
        if (ObjectUtil.isNotNull(saveDTO.getSchedulingEvent())){
            PcSchedulingEvent pcSchedulingEvent = BeanUtil.toBean(saveDTO.getSchedulingEvent(), PcSchedulingEvent.class);
            schedulingEventService.updateById(pcSchedulingEvent);
            //保存事件消息

            //保存统计数据
//            if (CollUtil.isNotEmpty(saveDTO.getSchedulingEvent().getStatisticsList())){
//                for (SchedulingEventStatisticsVO schedulingEventStatisticsVO : saveDTO.getSchedulingEvent().getStatisticsList()) {
//                    PcSchedulingEventStatistics pcSchedulingEventStatistics = pcSchedulingEventStatisticsService.getById(schedulingEventStatisticsVO.getId());
//                    BeanUtil.copyProperties(schedulingEventStatisticsVO, pcSchedulingEventStatistics);
//                    pcSchedulingEventStatisticsService.updateById(pcSchedulingEventStatistics);
//                }
//            }

        }

    }
    @Transactional(rollbackFor = Exception.class)
    public void removeEvent(String pcDrillId, String pcDrillDisasterEventId,String pcDrillDisasterId) {
        baseMapper.delete(
                Wrappers.<PcDrillDisaster>lambdaQuery()
                        .eq(PcDrillDisaster::getPcDrillId, pcDrillId)
                        .eq(PcDrillDisaster::getId,pcDrillDisasterId)
        );
        pcDrillDisasterEventMapper.delete(
                Wrappers.<PcDrillDisasterEvent>lambdaQuery()
                        .eq(PcDrillDisasterEvent::getPcDrillId, pcDrillId)
                        .eq(PcDrillDisasterEvent::getId,pcDrillDisasterEventId)
        );
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cleanEvent(String pcDrillId) {
        baseMapper.delete(Wrappers.<PcDrillDisaster>lambdaQuery().eq(PcDrillDisaster::getPcDrillId, pcDrillId));
        pcDrillDisasterEventMapper.delete(Wrappers.<PcDrillDisasterEvent>lambdaQuery().eq(PcDrillDisasterEvent::getPcDrillId, pcDrillId));
    }

    @Override
    public void cloneEvent(String pcDrillId,String newPcDrillId) {
        List<PcDrillDisaster> disasterList = baseMapper.selectList(
                Wrappers.<PcDrillDisaster>lambdaQuery()
                        .eq(PcDrillDisaster::getSourceType, SourceTypeEnum.REPOSITORY.getCode())
                        .eq(PcDrillDisaster::getPcDrillId, pcDrillId).orderByAsc(PcDrillDisaster::getIdx)
        );

        for (PcDrillDisaster pcDrillDisaster : disasterList) {
            String pcDrillDisasterId = pcDrillDisaster.getId();;
            pcDrillDisaster.setId(null)
                    .setCreateBy(null)
                    .setUpdateBy(null)
                    .setCreateTime(null)
                    .setUpdateTime(null);
            pcDrillDisaster.setPcDrillId(newPcDrillId);
            baseMapper.insert(pcDrillDisaster);
            List<PcDrillDisasterEvent> disasterEventList = pcDrillDisasterEventMapper.selectList(
                    Wrappers.<PcDrillDisasterEvent>lambdaQuery()
                            .eq(PcDrillDisasterEvent::getPcDrillId, pcDrillId)
                            .eq(PcDrillDisasterEvent::getIsDeleted, StatusEnum.FALSE.getCode())
                            .eq(PcDrillDisasterEvent::getPcDrillDisasterId,pcDrillDisasterId)
            );
            for (PcDrillDisasterEvent pcDrillDisasterEvent : disasterEventList) {
                String oldDisasterEventId=pcDrillDisasterEvent.getId();
                pcDrillDisasterEvent
                        .setId(null)
                        .setCreateBy(null)
                        .setUpdateBy(null)
                        .setCreateTime(null)
                        .setUpdateTime(null);
                pcDrillDisasterEvent.setStatus(DisasterEventStatusEnum.TO_BE_ISSUED.getCode());
                pcDrillDisasterEvent.setPcDrillId(newPcDrillId);
                pcDrillDisasterEvent.setPcDrillDisasterId(pcDrillDisaster.getId());
                pcDrillDisasterEvent.setActualSubmitTime(null);
                pcDrillDisasterEventMapper.insert(pcDrillDisasterEvent);

                //克隆消息的附件
                List<SystemFileBusiness> list = systemFileBusinessService.list(
                        Wrappers.<SystemFileBusiness>lambdaQuery()
                                .eq(SystemFileBusiness::getRelatedId, oldDisasterEventId)
                                .eq(SystemFileBusiness::getType, SystemFileBusinessConstant.TYPE_PC_DRILL_DISASTER_EVENT)
                );
                for (SystemFileBusiness systemFileBusiness : list) {
                    systemFileBusiness.setId(null)
                            .setCreateBy(null)
                            .setUpdateBy(null)
                            .setCreateTime(null)
                            .setUpdateTime(null);
                    systemFileBusiness.setRelatedId(pcDrillDisasterEvent.getId());
                }
                systemFileBusinessService.saveBatch(list);

            }
        }
    }

    @Override
    public PcDrillDisasterVO detailEvent(String pcDrillId) {
        PcDrill pcDrill = pcDrillMapper.selectById(pcDrillId);
        Assert.notNull(pcDrill,"演练【{}】不存在",pcDrillId);

        List<PcDrillDisaster> disasterList = baseMapper.selectList(
             Wrappers.<PcDrillDisaster>lambdaQuery()
                    .eq(PcDrillDisaster::getPcDrillId, pcDrillId).orderByAsc(PcDrillDisaster::getIdx)
        );
        List<PcDrillDisasterEvent> disasterEventList = pcDrillDisasterEventMapper.selectList(
                Wrappers.<PcDrillDisasterEvent>lambdaQuery()
                        .eq(PcDrillDisasterEvent::getPcDrillId, pcDrillId)
                        .eq(PcDrillDisasterEvent::getIsDeleted, StatusEnum.FALSE.getCode())
                        .orderByDesc(PcDrillDisasterEvent::getSubmitTime)
        );
        Optional<PcDrillDisaster> mainEvent = disasterList.stream().filter(s -> EventTypeEnum.MAIN_EVENT.getCode().equals(s.getEventType())).findFirst();
        PcDrillDisasterOrgVO pcDrillDisasterOrgVO = new PcDrillDisasterOrgVO();
        if (mainEvent.isPresent() && StrUtil.isNotBlank(mainEvent.get().getPcPlanId())) {
            List<PcDrillDutyOrgVO> drillDutyOrgList = pcDrillDutyOrgService.getDrillDutyOrg(pcDrillId, mainEvent.get().getPcPlanId(),null);
            if (CollUtil.isNotEmpty(drillDutyOrgList)){
                pcDrillDisasterOrgVO = getPlanDuty(mainEvent.get().getPcPlanId(), false);
                pcDrillDisasterOrgVO.setDutyOrgDeptList(drillDutyOrgList);
            }else {
                pcDrillDisasterOrgVO = getPlanDuty(mainEvent.get().getPcPlanId(), true);
            }
        }else {
            List<PcDrillDutyOrgVO> drillDutyOrgList = pcDrillDutyOrgService.getDrillDutyOrg(pcDrillId, null,null);
            pcDrillDisasterOrgVO = getPlanDuty(null, false);
            if (CollUtil.isNotEmpty(drillDutyOrgList)){
                pcDrillDisasterOrgVO.setDutyOrgDeptList(drillDutyOrgList);
            }
            else {
                //没有主事件，调用默认的组织架构
                 drillDutyOrgList = ForestNodeMerger.merge(basicDutyOrgService.selectList(new BasicDutyOrgTreeDTO())
                        .stream()
                        .map(s -> BeanUtil.toBean(s,PcDrillDutyOrgVO.class))
                        .collect(Collectors.toList()));
                pcDrillDisasterOrgVO.setDutyOrgDeptList(drillDutyOrgList);
            }
        }
        List<PcDrillDisasterEventListVO> drillDisasterEventList = disasterEventList.stream().map(disasterEvent -> {
            PcDrillDisasterEventListVO listVO = BeanUtil.toBean(disasterEvent,PcDrillDisasterEventListVO.class);
            if (ObjectUtil.isNotNull(listVO.getPcDrillDisasterId())){
                PcDrillDisaster pcDrillDisaster = baseMapper.selectById(listVO.getPcDrillDisasterId());
                if (ObjectUtil.isNotNull(pcDrillDisaster)){
                    listVO.setEventType(pcDrillDisaster.getEventType());
                }
            }
            //添加type，level的名称
            if (StrUtil.isNotBlank(listVO.getType())){
                String dictValue = DictCache.getDictValue(PcDisasterConstant.DISASTER_TYPE, listVO.getType());
                listVO.setTypeName(dictValue);
            }
            if (StrUtil.isNotBlank(listVO.getLevel())){
                String dictValue = DictCache.getDictValue(PcDisasterConstant.EVENT_LEVEL, listVO.getLevel());
                listVO.setLevelName(dictValue);
            }
            //附件信息
            List<SystemFile> fileList = systemFileService.getListById(disasterEvent.getId(),SystemFileBusinessConstant.TYPE_PC_DRILL_DISASTER_EVENT);
            listVO.setFileList(fileList);
            return listVO;
        }).collect(Collectors.toList());


        PcDrillDisasterVO pcDrillDisasterVO = new PcDrillDisasterVO();
        BeanUtil.copyProperties(pcDrillDisasterOrgVO,pcDrillDisasterVO);
        pcDrillDisasterVO.setName(pcDrill.getName());
        pcDrillDisasterVO.setPlanStartTime(pcDrill.getPlanStartTime());
        pcDrillDisasterVO.setPlanEndTime(pcDrill.getPlanEndTime());
        pcDrillDisasterVO.setDisasterList(disasterList);
        pcDrillDisasterVO.setDisasterEventList(drillDisasterEventList);
        //应急指挥事件
        PcSchedulingEventVO pcSchedulingEventVO =null;
        if (DrillTypeEnum.EMERGENCY_COMMAND.getCode().equals(pcDrill.getDrillType())){

            pcSchedulingEventVO=schedulingEventService.getDetailEventByDrillId(pcDrill.getId());
            if (null!=pcSchedulingEventVO){
                //新流程，指挥生成的演练时，事件消息只有一条
                PcDrillDisasterEvent drillDisasterEvent=disasterEventList.get(0);
                //保留原来的id
                BeanUtils.copyProperties(drillDisasterEvent,pcSchedulingEventVO,"id");
//                PcSchedulingEventVO eventVO=new PcSchedulingEventVO();
//                BeanUtils.copyProperties(drillDisasterEvent,eventVO);
//                eventVO.setDrillId(drillDisasterEvent.getPcDrillId());
                if(StringUtils.hasText(pcSchedulingEventVO.getTyphoonNo()))
                {
                    OdsTyphoonVO typhoon = tfService.getTyphoon(pcSchedulingEventVO.getTyphoonNo());
                    pcSchedulingEventVO.setTyphoon(typhoon);
                }

            }

        }

        if (DrillTypeEnum.PLANNING_DRILL.getCode().equals(pcDrill.getDrillType())){
            if (mainEvent.isPresent())
            {
                pcSchedulingEventVO = new PcSchedulingEventVO();
                pcSchedulingEventVO.setTyphoonNo(mainEvent.get().getTyphoonNo());
            }
        }
        pcDrillDisasterVO.setSchedulingEvent(pcSchedulingEventVO);

        return pcDrillDisasterVO;
    }

    @Override
    public PcDrillOrgUsersVO getOrgUsers(String pcDrillId,String orgId,String deptId) {
        PcDrillOrgUsersVO orgUsersVO=new PcDrillOrgUsersVO();
        List<SystemDept> depts=null;
        List<String> deptIdsforQueryUser=null;
        //返回根节点
        if(null==deptId)
        {
            depts=systemDeptService.getRootDepts();
            //返回根节点，要加上测试机构
//            SystemDept testDept=new SystemDept();
//            testDept.setDeptName("测试机构")
//                .setRoot(true)
//                .setId("test-dept-1");
//            depts.add(testDept);
            deptIdsforQueryUser=depts.stream().map(SystemDept::getId).collect(Collectors.toList());
        }
        else
        {
            //获取子部门
            depts=systemDeptService.getChildDepts(deptId);
            //数据库里面父级节点的数据存在，所以这里直接用前端传递的父级部门id查询，
            deptIdsforQueryUser=Arrays.asList(deptId);
        }
        orgUsersVO.setOrgs(depts);
        List<SystemUserVo> selectUsers=getSelectUsers(pcDrillId,orgId,deptId);
        //选中的人员
        orgUsersVO.setSelectUsers(selectUsers);
        List<String> selectUserIds=selectUsers.stream().map(SystemUserVo::getId).collect(Collectors.toList());
        //没有选中的人员
        List<SystemUserVo> users=systemDeptService.getUsers(deptIdsforQueryUser,selectUserIds,null);
        orgUsersVO.setOrgUsers(users);

        return orgUsersVO;
    }

    @Override
    public PcDrillOrgUsersVO queryUsers(String pcDrillId, String orgId, String keyword) {
        PcDrillOrgUsersVO pcDrillOrgUsersVO=new PcDrillOrgUsersVO();
        List<String> selectUserIds=null;
        List<SystemUserVo> selectUserVos=new ArrayList<>();
        //先在已选中的人中查找，如果有则返回，如果没有，再继续查找通讯录的数据
        //勾选的组织架构成员单位
        //目前下面的逻辑，不兼容预案查询人员的情况，并且注释掉，对功能基本没有影响，就是选中的人不能显示在最前面
//        List<PcDrillDutyUser> selectUsers = pcDrillDutyUserMapper.selectList(
//                Wrappers.lambdaQuery(PcDrillDutyUser.class)
//                        .eq(PcDrillDutyUser::getPcDrillOrgId,orgId)
//                        .eq(PcDrillDutyUser::getPcDrillId, pcDrillId)
//                        .like(StringUtils.hasText(keyword),PcDrillDutyUser::getPrincipalNames,keyword));
//
//        if(!CollectionUtils.isEmpty(selectUsers))
//        {
//            selectUsers.stream().forEach(user->{
//                buildSystemUserVo(user.getPrincipalIds(),user.getPrincipalNames(),user.getPrincipalPhones(),user.getDeptId(),user.getDeptName(),keyword,selectUserVos);
//
//            });
//            pcDrillOrgUsersVO.setSelectUsers(selectUserVos);
//            selectUserIds=selectUserVos.stream().map(SystemUserVo::getId).collect(Collectors.toList());
//        }
        List<SystemUserVo> orgUsers=systemDeptService.getUsers(null,selectUserIds,keyword);
        pcDrillOrgUsersVO.setOrgUsers(orgUsers);
        //目前城阳项目的逻辑，一个用户只会在一个叶子部门，所以下面的逻辑注释，如果后面有需要把下面的逻辑恢复，注意不能直接使用，需要修改
//        List<SystemUserVo> filterUsers=new ArrayList<>();
//        if(!CollectionUtils.isEmpty(orgUsers))
//        {
//            List<SystemDept> depts=systemDeptService.getRootDepts();
//            List<String> deptIds=depts.stream().map(SystemDept::getId).collect(Collectors.toList());
//            //这里是根据名字去筛选，会吧一个人在各个分组的记录都查出来，所以要过滤一下，和上不太一样
//            Map<String,List<SystemUserVo>> orgUsersMap=orgUsers.stream().collect(Collectors.groupingBy(SystemUserVo::getId));
//            orgUsersMap.keySet().forEach(userId->{
//                List<SystemUserVo> suvs=orgUsersMap.get(userId);
//                SystemUserVo leafNode=getLeafNode(deptIds,suvs);
//                if(leafNode!=null)
//                {
//                    filterUsers.add(leafNode);
//                }
//
//            });
//            pcDrillOrgUsersVO.setOrgUsers(filterUsers);
//        }
        return pcDrillOrgUsersVO;
    }

    @Override
    public List<SystemUserVo> queryOrgUsers(String deptId) {
        List<String> deptIdsforQueryUser=Arrays.asList(deptId);
        List<SystemUserVo> deptUsers=systemDeptService.getUsers(deptIdsforQueryUser,null,null);
        return deptUsers;
    }

    @Override
    public PcDrillOrgUsersVO searchUsers(String keyword) {
        PcDrillOrgUsersVO pcDrillOrgUsersVO=new PcDrillOrgUsersVO();
        List<SystemUserVo> orgUsers=systemDeptService.getUsers(null,null,keyword);
        List<SystemUserVo> filterUsers=new ArrayList<>();
        if(!CollectionUtils.isEmpty(orgUsers))
        {
            List<SystemDept> depts=systemDeptService.getRootDepts();
            List<String> deptIds=depts.stream().map(SystemDept::getId).collect(Collectors.toList());
            //这里是根据名字去筛选，会吧一个人在各个分组的记录都查出来，所以要过滤一下
            Map<String,List<SystemUserVo>> orgUsersMap=orgUsers.stream().collect(Collectors.groupingBy(SystemUserVo::getId));
            orgUsersMap.keySet().forEach(userId->{
                List<SystemUserVo> suvs=orgUsersMap.get(userId);
                SystemUserVo leafNode=getLeafNode(deptIds,suvs);
                if(leafNode!=null)
                {
                    filterUsers.add(leafNode);
                }

            });
            pcDrillOrgUsersVO.setOrgUsers(filterUsers);
        }
        return pcDrillOrgUsersVO;
    }

    @Override
    public List<SystemDeptVo> queryOrgs(String deptId) {
        List<SystemDeptVo> depts=null;
        //返回根节点
        if(null==deptId)
        {
            //根节点应该都是有子部门的，这里暂时写死
//            Integer leaf=0;
//            depts=systemDeptService.getRootDepts().stream().map(dept -> SystemDeptVo.fromSystemDept(dept,leaf)).collect(Collectors.toList());
            List<SystemDeptTreeVO> systemDeptTreeVOS = systemDeptService.deptTree();
            depts=systemDeptTreeVOS.stream().map(treeVo -> SystemDeptVo.fromSystemDeptTreeVo(treeVo)).collect(Collectors.toList());

        }
        else
        {
            //获取子部门
            depts=systemDeptService.queryChildDepts(deptId);
            //数据库里面父级节点的数据存在，所以这里直接用前端传递的父级部门id查询，
        }
        return depts;
    }

    @Override
    public List<SystemUserVo> queryOrgSelectUsers(String pcDrillId, String orgId) {
        return getSelectUsers(pcDrillId,orgId,null);
    }


    private SystemUserVo getLeafNode(List<String> deptIds,List<SystemUserVo> userVos)
    {


        boolean hasRoot=false;
        SystemUserVo root=null;
        for(SystemUserVo userVo:userVos)
        {
            if(deptIds.contains(userVo.getDeptId()))
            {
                hasRoot=true;
                root=userVo;
                break;
            }
        }
        if(!hasRoot)
        {
            return null;
        }
        return findLeafUserVo(root,userVos);
    }

    /**
     * 递归查找叶子节点
     * @param parent
     * @param userVos
     * @return
     */
    private SystemUserVo findLeafUserVo(SystemUserVo parent,List<SystemUserVo> userVos)
    {
        Optional<SystemUserVo> userVo=userVos.stream().filter(u->null!=u.getParentId() && u.getParentId().equals(parent.getDeptId())).findFirst();
        if(userVo.isPresent())
        {
            return findLeafUserVo(userVo.get(),userVos);
        }
        return parent;
    }


    private SystemDeptTreeVO getSelectDept(List<SystemDeptTreeVO> deptTreeVOS,String deptId)
    {
        SystemDeptTreeVO result=null;
        for(SystemDeptTreeVO deptTreeVO:deptTreeVOS)
        {

            if(deptTreeVO.getId().equals(deptId))
            {
                result=deptTreeVO;
                break;
            }
            result=getSelectDept(deptTreeVO.getChildren(),deptId);
            if(result!=null)
            {
                break;
            }

        }
        return result;
    }

    /**
     * 获取已选中的人
     * @param pcDrillId
     * @param orgId
     * @param deptId
     * @return
     */
    private List<SystemUserVo> getSelectUsers(String pcDrillId,String orgId,String deptId)
    {
        List<SystemDeptTreeVO> deptTreeVOS=systemDeptService.deptTree();
        SystemDeptTreeVO dept=null;
        //找出选择的部门,这里从tree树中去递归查找，也可以通过sql，递归查询数据库去查找
        if(null!=deptId)
        {
            dept=getSelectDept(deptTreeVOS,deptId);

        }

        List<PcDrillDutyOrgVO> drillDutyOrgList = pcDrillDutyOrgService.getDrillDutyOrg(pcDrillId, null,orgId);
        if(CollectionUtils.isEmpty(drillDutyOrgList))
        {
            return Collections.emptyList();
        }
        //因为加上了orgId，这里只有一个元素
        List<PcDrillDutyOrgUserVO> users=drillDutyOrgList.get(0).getDutyOrgDeptList();
        List<SystemUserVo> userVos=new ArrayList<>();
        for(PcDrillDutyOrgUserVO user:users){
            //如果选择了某个部门，需要过滤出选中的部门的用户
            //deptId不为空，则应该缓存部门树中SystemDeptTreeVO，应该能找到对应的部门，所以这里不再判断dept是否为空
            if(deptId!=null)
            {
                if(dept.getId().equals(user.getDeptId()))
                {
                    buildSystemUserVo(user.getPrincipalIds(),user.getPrincipalNames(),user.getPrincipalPhones(),user.getDeptId(),user.getDeptName(),null,userVos);
                }
                else{
                    SystemDeptTreeVO hasDept=getSelectDept(dept.getChildren(),user.getDeptId());
                    //不为空，则表示该PcDrillDutyOrgUserVO的部门，是所选的部门的一个子部门
                    if(null!=hasDept)
                    {
                        buildSystemUserVo(user.getPrincipalIds(),user.getPrincipalNames(),user.getPrincipalPhones(),user.getDeptId(),user.getDeptName(),null,userVos);
                    }
                }
            }
            else
            {
                buildSystemUserVo(user.getPrincipalIds(),user.getPrincipalNames(),user.getPrincipalPhones(),user.getDeptId(),user.getDeptName(),null,userVos);
            }

        };
        return userVos;
    }

    private void buildSystemUserVo(String principalIds,String principalNames,String principalPhones,String deptId,String deptName,String keyword,List<SystemUserVo> userVos)
    {
        List<String> userIds=StrUtil.split(principalIds,",");
        List<String> userNames=StrUtil.split(principalNames,",");
        List<String> usePhones=StrUtil.split(principalPhones,",");
        for(int x=0;x<userIds.size();x++)
        {
            SystemUserVo userVo=new SystemUserVo();


            if(null!=keyword)
            {
                if(userNames.get(x).contains(keyword))
                {
                    userVo.setDeptId(deptId)
                            .setDeptName(deptName)
                            .setRealName(userNames.get(x))
                            .setId(userIds.get(x));
                    if(!"null".equals(usePhones.get(x)))
                    {
                        userVo.setPhone(usePhones.get(x));
                    }
                    userVos.add(userVo);
                }
            }
            else
            {

                userVo.setDeptId(deptId)
                        .setDeptName(deptName)
                        .setRealName(userNames.get(x))
                        .setId(userIds.get(x));
                if(!"null".equals(usePhones.get(x)))
                {
                    userVo.setPhone(usePhones.get(x));
                }
                userVos.add(userVo);
            }

        }
    }


    @Override
    public List<CommandDrillOrgVo> getSchedulingDrillOrgs(String drillId) {
        List<PcDrillDutyOrgVO> drillDutyOrgList = pcDrillDutyOrgService.getDrillDutyOrg(drillId, null,null);
        if(CollectionUtils.isEmpty(drillDutyOrgList))
        {
            return Collections.emptyList();
        }
        return drillDutyOrgList.stream().map(org->CommandDrillOrgVo.fromPcDrillDutyOrgVO(org)).collect(Collectors.toList());
    }

    @Override
    public List<CommandDrillDisasterVo> getDisasterList(String drillId) {

        List<PcDrillDisasterEvent> disasterEvents=pcDisasterEventService.list(Wrappers.lambdaQuery(PcDrillDisasterEvent.class)
                .eq(PcDrillDisasterEvent::getPcDrillId, drillId)
                .eq(PcDrillDisasterEvent::getIsDeleted, StatusEnum.FALSE.getCode())
        .orderByDesc(PcDrillDisasterEvent::getSubmitTime));
        Map<String,List<PcDrillDisasterEvent>> disasterEventsMap=disasterEvents.stream().collect(Collectors.groupingBy(PcDrillDisasterEvent::getPcDrillDisasterId,LinkedHashMap::new,Collectors.toList()));
        //灾害人数
        //todo 这里应该考虑每个事件都有这些人数
//        List<PcSchedulingEventStatistics> statistics=pcSchedulingEventStatisticsService.list(Wrappers.lambdaQuery(PcSchedulingEventStatistics.class)
//                .eq(PcSchedulingEventStatistics::getDrillId, drillId));
//        Map<String,PcSchedulingEventStatistics> statisticsMap=statistics.stream().collect(Collectors.toMap(PcSchedulingEventStatistics::getPcDrillDisasterId,v->v));
        //事件消息


        return disasterEventsMap.keySet().stream().map(disasterId->{
            PcDrillDisaster disaster=this.getById(disasterId);
            CommandDrillDisasterVo disasterVo=new CommandDrillDisasterVo();
            BeanUtils.copyProperties(disaster,disasterVo);
            List<PcDrillDisasterEvent> events=disasterEventsMap.get(disaster.getId());
            if(!CollectionUtils.isEmpty(events))
            {
                //来源部门取第一条消息的部门，事件本身没有部门
                disasterVo.setSourceDept(events.get(0).getSource());
                List<CommandDrillDisasterEventVo> eventMessages=events.stream().map(CommandDrillDisasterEventVo::fromPcDrillDisasterEvent).collect(Collectors.toList());
                disasterVo.setEventMessages(eventMessages);

                //获取经纬度,geometry信息，目前指挥类型的演练，一般都是一个事件对应一个事件消息
                disasterVo.setLatitude(events.get(0).getLatitude())
                        .setLongitude(events.get(0).getLongitude())
                        .setGeometry(events.get(0).getGeometry());
            }
            //有的事件是没有统计信息的
            List<PcSchedulingEventStatistics> statistics=pcSchedulingEventStatisticsService.list(Wrappers.lambdaQuery(PcSchedulingEventStatistics.class)
                    .eq(PcSchedulingEventStatistics::getDrillId, drillId)
            .eq(PcSchedulingEventStatistics::getPcDrillDisasterId,disaster.getId()));
            if(!CollectionUtils.isEmpty(statistics))
            {
                Integer deathNum=statistics.stream().mapToInt(PcSchedulingEventStatistics::getDeathNum).sum();
                Integer missNum=statistics.stream().mapToInt(PcSchedulingEventStatistics::getMissNum).sum();
                Integer injuredNum=statistics.stream().mapToInt(PcSchedulingEventStatistics::getInjuredNum).sum();

                disasterVo.setDeathNum(deathNum)
                        .setMissNum(missNum)
                        .setInjuredNum(injuredNum);
            }

            return disasterVo;
        }).collect(Collectors.toList());
    }

    private List<PcDrillDutyOrg> getDutyOrgs(String drillId,String disasterEventId)
    {
        List<String> groupIds = pcDrillPlanDetailMapper.selectList(
                Wrappers.lambdaQuery(PcDrillPlanDetail.class)
                        .eq(PcDrillPlanDetail::getPcDrillId, drillId)
                        .eq(PcDrillPlanDetail::getPcDrillDisasterEventId,disasterEventId)
                        .select(PcDrillPlanDetail::getGroupId)
        ).stream().map(PcDrillPlanDetail::getGroupId).distinct().collect(Collectors.toList());
        if(CollectionUtils.isEmpty(groupIds))
        {
            return Collections.emptyList();
        }
        return  pcDrillDutyOrgMapper.selectList(
                Wrappers.<PcDrillDutyOrg>lambdaQuery()
                        .eq(PcDrillDutyOrg::getPcDrillId, drillId)
                        .in(PcDrillDutyOrg::getId,groupIds)
                        .orderByAsc(PcDrillDutyOrg::getIdx));
    }

    @Override
    public List<CommandDrillEventAndPlanVo> getEventAndPlan(String drillId, String drillDisasterId) {

        List<PcDrillDisasterEvent> events=pcDisasterEventService.list(Wrappers.lambdaQuery(PcDrillDisasterEvent.class)
                .eq(PcDrillDisasterEvent::getPcDrillId, drillId)
                .eq(PcDrillDisasterEvent::getPcDrillDisasterId,drillDisasterId)
        .orderByAsc(PcDrillDisasterEvent::getCreateTime));
        if(CollectionUtils.isEmpty(events))
        {
            return Collections.emptyList();
        }
        return events.stream().map(event->{
            CommandDrillEventAndPlanVo eventAndPlanVo=new CommandDrillEventAndPlanVo();
            BeanUtils.copyProperties(event,eventAndPlanVo);
            List<PcDrillDutyOrg> orgs=getDutyOrgs(drillId,event.getId());
            if(CollectionUtils.isEmpty(orgs))
            {
                return eventAndPlanVo;
            }
            //方案详情
            List<PcDrillPlanVO> planVOs=pcDrillPlanList.pcDrillPlanList(drillId,event.getId(),null,null);
            /**
             * 将方案详情里面的feedbackStatus和status合并到status
             * 1.待提交
             * 2.待审批(方案提交)
             * 3.待反馈
             * 4.审批不通过(方案提交)
             * 5.待审批(任务完成提交)
             * 6.已完成
             * 7.审批不通过(任务完成提交)
             */
            planVOs.stream().forEach(plan->setUpPlanStatus(plan.getDetailList()));
            List<CommandDrillPlanGroupVo> groupVos=orgs.stream().map(org->{
                CommandDrillPlanGroupVo groupVo=new CommandDrillPlanGroupVo();
                BeanUtils.copyProperties(org,groupVo);
                planVOs.stream().filter(p->p.getGroupId().equals(org.getId())).findFirst().ifPresent(vo->{
                    List<PcDrillPlanDetailVO> details=vo.getDetailList();
                    if(!CollectionUtils.isEmpty(details))
                    {
                        groupVo.setDetailList(details);
                        groupVo.setTaskTotal(details.size());
                        Long finishCount=details.stream().filter(d->CommandSysWorkPlanStatusEnum.COMPLETE.getCode().equals(d.getStatus())).count();
                        groupVo.setFinishTaskTotal(finishCount.intValue());
                    }
                });

                return groupVo;
            }).collect(Collectors.toList());
            eventAndPlanVo.setGroupVos(groupVos);
            return eventAndPlanVo;
        }).collect(Collectors.toList());

    }

    @Override
    public List<SystemFile> getPlanFile(String pcDrillId, PlanFileTypeEnum type) {
        PcDrill pcDrill =pcDrillMapper.selectById(pcDrillId);
        String planId=pcDrill.getPcPlanId();
        List<SystemFileBusiness> sfb=systemFileBusinessService.list(Wrappers.lambdaQuery(SystemFileBusiness.class).eq(SystemFileBusiness::getRelatedId,planId).eq(SystemFileBusiness::getType,type.getCode()));
        if(CollectionUtils.isEmpty(sfb))
        {
            return Collections.emptyList();
        }
        List<String> fileIds=sfb.stream().map(SystemFileBusiness::getFileId).collect(Collectors.toList());
        List<SystemFile> files=systemFileService.list(Wrappers.lambdaQuery(SystemFile.class).in(SystemFile::getId,fileIds));
        return files;
    }

    /**
     * 将方案详情里面的feedbackStatus和status合并到status
     */
    private void setUpPlanStatus(List<PcDrillPlanDetailVO> detailVOS)
    {
        detailVOS.stream().forEach(detail->{
            if(TaskStatusEnum.WAIT_APPROVAL.getCode().equals(detail.getFeedbackStatus()))
            {
                detail.setStatus(CommandSysWorkPlanStatusEnum.TASK_FINISH_WAIT_COMMIT.getCode());
            }
            if(TaskStatusEnum.PASS.getCode().equals(detail.getFeedbackStatus()))
            {
                detail.setStatus(CommandSysWorkPlanStatusEnum.COMPLETE.getCode());
            }
            if(TaskStatusEnum.FAIL.getCode().equals(detail.getFeedbackStatus()))
            {
                detail.setStatus(CommandSysWorkPlanStatusEnum.TASK_FINISH_FAIL.getCode());
            }

        });
    }

    @Override
    public PcDrillDisasterOrgVO getPlanDuty(String planId,boolean showPlanOrg){
        PcDrillDisasterOrgVO pcDrillDisasterOrgVO = new PcDrillDisasterOrgVO();
        List<PcPlanDutyDeptVO> pcPlanDutyDeptList = Lists.newArrayList();
        pcPlanDutyDeptList = pcPlanDutyDeptService.selectPlanDuty(planId);
        if (showPlanOrg){
            List<PcPlanDutyOrg> planDutyOrgList = pcPlanDutyOrgService.list(
                    Wrappers.lambdaQuery(PcPlanDutyOrg.class)
                            .eq(PcPlanDutyOrg::getPcPlanId, planId)
                            .orderByDesc(PcPlanDutyOrg::getParentId)
                            .orderByAsc(PcPlanDutyOrg::getIdx)
            );
            //勾选的组织架构成员单位
            //勾选的人员
            List<PcPlanOrgUser> planOrgUsers = pcPlanOrgUserMapper.selectList(
                    Wrappers.lambdaQuery(PcPlanOrgUser.class)
                            .eq(PcPlanOrgUser::getPcPlanId, planId)
            );
            List<PcPlanDutyDeptVO> finalPcPlanDutyDeptList = pcPlanDutyDeptList;
            List<PcDrillDutyOrgVO> drillDutyOrgList = planDutyOrgList.stream().map(pcPlanDutyOrg -> {
                PcDrillDutyOrgVO pcDrillDutyOrgVO = BeanUtil.toBean(pcPlanDutyOrg, PcDrillDutyOrgVO.class);
                List<PcDrillDutyOrgUserVO> dutyOrgUserList = planOrgUsers.stream()
                        .filter(s -> pcPlanDutyOrg.getId().equals(s.getPcPlanOrgId()))
                        .map(s -> {
                            PcDrillDutyOrgUserVO pcDrillDutyOrgUserVO = BeanUtil.toBean(s, PcDrillDutyOrgUserVO.class);
//                            Optional<PcPlanDutyDeptVO> first = finalPcPlanDutyDeptList.stream().filter(it -> it.getDeptId().equals(s.getDeptId())).findFirst();
//                            if (first.isPresent()){
//                                pcDrillDutyOrgUserVO.setDeptName(first.get().getDeptName());
//                                pcDrillDutyOrgUserVO.setDuty(first.get().getDuty());
//                            }
                            return pcDrillDutyOrgUserVO;
                        })
                        .collect(Collectors.toList());
                pcDrillDutyOrgVO.setDutyOrgDeptList(dutyOrgUserList);
                return pcDrillDutyOrgVO;
            }).collect(Collectors.toList());
            pcDrillDisasterOrgVO.setDutyOrgDeptList(ForestNodeMerger.merge(drillDutyOrgList));

        }

//        Set<String> deptIdList = pcPlanDutyDeptList.stream().map(PcPlanDutyDeptVO::getDeptId).collect(Collectors.toSet());
//        List<SystemDeptUser> list = Lists.newArrayList();
//        if (CollUtil.isNotEmpty(deptIdList)){
//            list = systemDeptUserService.list(
//                    Wrappers.lambdaQuery(SystemDeptUser.class).in(SystemDeptUser::getDeptId, deptIdList)
//            );
//            //查询手机号
//            List<String> userIds=list.stream().map(SystemDeptUser::getUserId).collect(Collectors.toList());
//            List<SystemUser> userList=systemUserService.list(Wrappers.lambdaQuery(SystemUser.class)
//                    .in(SystemUser::getId, userIds)
//                    .select(SystemUser::getId,SystemUser::getPhone)
//            );
//            Map<String,SystemUser> userPhones=userList.stream().collect(Collectors.toMap(SystemUser::getId,v->v));
//            pcDrillDisasterOrgVO.setDeptUserList(
//                    list.stream().map(s -> {
//                        DeptUserVO deptUserVO = new DeptUserVO();
//                        deptUserVO.setId(s.getUserId());
//                        deptUserVO.setDeptId(s.getDeptId());
//                        deptUserVO.setName(s.getUserName());
//                        deptUserVO.setDeptName(s.getDeptName());
//                        deptUserVO.setPhone(userPhones.get(s.getUserId()).getPhone());
//                        return deptUserVO;
//                    }).collect(Collectors.toList())
//            );
//        }

//        pcDrillDisasterOrgVO.setDutyDutyOrgUserList(
//                        pcPlanDutyDeptList.stream().map(s -> BeanUtil.toBean(s,PcDrillDutyOrgUserVO.class)).collect(Collectors.toList())
//        );
        //测试，加上虚拟节点
//        List<SystemDeptTreeVO> treeVOS=systemDeptService.tree();
//        SystemDeptTreeVO testDept=new SystemDeptTreeVO();
//        testDept.setChildren(Collections.emptyList());
//        testDept.setHasChildren(false);
//        testDept.setDeptName("测试机构")
//                .setRoot(true)
//                .setId("test-1");
//        treeVOS.add(testDept);
//        pcDrillDisasterOrgVO.setDutyDutyOrgUserList(treeVOS);
        return pcDrillDisasterOrgVO;

    }

    @Override
    public PcDrillDisasterOrgVO getPlanOrgUsers(String planId) {
        PcDrillDisasterOrgVO orgVO=new PcDrillDisasterOrgVO();

        return orgVO;
    }

    @Override
    public PcDrillDisasterEventVO getDetail(PcDrillDisasterEventQueryDTO queryDTO) {
        PcDrillDisasterEventVO pcDrillDisasterEventVO = new PcDrillDisasterEventVO();
        String type = SystemFileBusinessConstant.TYPE_PC_DRILL_DISASTER_EVENT;
        if (StrUtil.isAllNotBlank(queryDTO.getPcDrillId(),queryDTO.getPcDrillDisasterEventId())){
            //从演练灾害事件上获取
            PcDrillDisasterEvent pcDrillDisasterEvent = pcDrillDisasterEventMapper.selectOne(
                    Wrappers.<PcDrillDisasterEvent>lambdaQuery()
                            .eq(PcDrillDisasterEvent::getPcDrillId, queryDTO.getPcDrillId())
                            .eq(PcDrillDisasterEvent::getId, queryDTO.getPcDrillDisasterEventId())
                            .last("limit 1")
            );
//            Assert.notNull(pcDrillDisasterEvent,"获取不到灾害事件");
            BeanUtil.copyProperties(pcDrillDisasterEvent,pcDrillDisasterEventVO);
        }else {
            Assert.notBlank(queryDTO.getPcDisasterEventId(),"灾害事件id不能为空");
            PcDisasterEvent pcDisasterEvent = pcDisasterEventMapper.selectById(queryDTO.getPcDisasterEventId());
//            Assert.notNull(pcDisasterEvent,"获取不到灾害事件");
            BeanUtil.copyProperties(pcDisasterEvent,pcDrillDisasterEventVO);
            type = SystemFileBusinessConstant.TYPE_PC_DISASTER_EVENT;
        }
        pcDisasterEventService.setDetailExtra(pcDrillDisasterEventVO,type);
        //设置用户所在机构id
        pcDrillDisasterEventVO.setGroupId(pcDrillDutyOrgService.getUserGroupId(queryDTO.getPcDrillId()));
        return pcDrillDisasterEventVO;
    }

    @Override
    public List<PcDisaster> presetEvent(String pcDrillId) {
        //先获取所有的突发事件
        List<PcDisaster> allDisasters=pcDisasterMapper.selectList(Wrappers.<PcDisaster>lambdaQuery()
                .eq(PcDisaster::getEventType, "2")
                .eq(PcDisaster::getDataStatus, CommonConstants.YES));
        if (ObjectUtil.isNotEmpty(allDisasters)){
            //过滤掉已经选择的突发事件
            //1.这里要从事件消息去过滤，因为事件加入演练，不一定会在PcDrillDisaster里面，预设事件目前添加的时候，没有在PcDrillDisaster添加记录
            //2.预设事件是1条消息不断添加的，这里要判断事件消息是否添加完
            return allDisasters.stream().filter(disaster->{

                List<PcDisasterEvent> allEvents=disasterEventService.list(Wrappers.<PcDisasterEvent>lambdaQuery()
                        .eq(PcDisasterEvent::getPcDisasterId, disaster.getId()));
                if(CollectionUtils.isEmpty(allEvents))
                {
                    return false;
                }
                //灾害事件消息个数
                int allEventsCount=allEvents.size();

                List<PcDrillDisasterEvent> drillEvents=pcDisasterEventService.list(Wrappers.<PcDrillDisasterEvent>lambdaQuery()
                        .eq(PcDrillDisasterEvent::getPcDrillId, pcDrillId)
                        .eq(PcDrillDisasterEvent::getPcDisasterId,disaster.getId())
                );
                //演练事件消息个数
                int drillEventsCount=drillEvents.size();
                if(allEventsCount!=drillEventsCount)
                {
                    return true;
                }
                return false;
            }).collect(Collectors.toList());


        }
        return Lists.newArrayList();
    }

    @Override
    public List<PcDrill> getDrillByTyphoonNo(String typhoonNo) {
        return baseMapper.getDrillByTyphoonNo(typhoonNo);
    }
}
